package com.smartlink.vn.fsharetools;

import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.swing.text.AttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultRedirectStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;

public class FshareTools {

    private final String USERNAME = "greytigerbm@gmail.com";
    private final String PASSWORD = "bayernmunich";
    private final String LOGIN_URL = "https://www.fshare.vn/login";
    private final String LOGOUT_URL = "https://www.fshare.vn/logout";
    private final String SAMPLE_URL = "https://www.fshare.vn/file/TGYH497DFT";
    private String sessionIdGet = "";
    private String sessionIdPost = "";
    private String location = "";
    private String fs_csrf = "";

    public void download(String url) throws IOException, Exception {
        CloseableHttpClient client = HttpClientBuilder.create().setRedirectStrategy(new DefaultRedirectStrategy() {

            @Override
            protected boolean isRedirectable(String method) {
                return false;
            }

            @Override
            public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
                return false;
            }

        }).build();
        HttpGet request = new HttpGet(url);
        String cookie = String.format("session_id=%s", sessionIdPost);
        request.addHeader("cookie", cookie);
        CloseableHttpResponse response = client.execute(request);
//        System.out.println(response.getStatusLine());
        Header[] headers = response.getAllHeaders();
        for (Header header : headers) {
            String name = header.getName();
//            System.out.println(String.format("%s: %s", name, header.getValue()));
            if (name.equalsIgnoreCase("location")) {
                location = header.getValue();
//                System.out.println("location: " + location);
                break;
            }
        }
        if (location.isEmpty()) {
            throw new Exception("Can't get location");
        }
        client.close();
        System.out.println("Link: " + url);
        System.out.println("Download link: " + location);
        Desktop.getDesktop().browse(new URI(location));
//        System.out.println("FINISH DOWNLOAD!");
    }

    public void loginGet() throws IOException, Exception {
        sessionIdGet = "";
        CloseableHttpClient client = HttpClientBuilder.create().build();
        HttpGet request = new HttpGet(LOGIN_URL);
        CloseableHttpResponse response = client.execute(request);
        Header[] headers = response.getAllHeaders();
        for (Header header : headers) {
            String name = header.getName();
//            System.out.println(String.format("%s: %s", name, header.getValue()));
            if (name.equalsIgnoreCase("Set-Cookie")) {
                HeaderElement[] elements = header.getElements();
                for (HeaderElement element : elements) {
                    String elementName = element.getName();
                    if (elementName.equalsIgnoreCase("session_id")) {
                        sessionIdGet = element.getValue();
//                        System.out.println("session_id GET: " + sessionIdGet);
                        break;
                    }
                }
            }
        }
        if (sessionIdGet.isEmpty()) {
            throw new Exception("Can't get session_id GET");
        }
//            writeResponseToFile(response, "D://LoginGet.html");
        fs_csrf = "";
        Reader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        HTMLEditorKit htmlKit = new HTMLEditorKit();
        HTMLDocument htmlDoc = (HTMLDocument) htmlKit.createDefaultDocument();
        htmlDoc.putProperty("IgnoreCharsetDirective", true);
        htmlKit.read(reader, htmlDoc, 0);
        for (HTMLDocument.Iterator iterator = htmlDoc.getIterator(HTML.Tag.INPUT); iterator.isValid(); iterator.next()) {
            AttributeSet attributes = iterator.getAttributes();
            String name = (String) attributes.getAttribute(HTML.Attribute.NAME);
            if (name.equalsIgnoreCase("fs_csrf")) {
                fs_csrf = (String) attributes.getAttribute(HTML.Attribute.VALUE);
//                    System.out.println("lt: " + ltVal);
                break;
            }
        }
        if (fs_csrf.isEmpty()) {
            throw new Exception("Can't get fs_csrf");
        }
//        System.out.println("FINISH LOGIN GET!");
        client.close();
    }

    public void loginPost() throws IOException, Exception {
        sessionIdPost = "";
        CloseableHttpClient client = HttpClientBuilder.create().setRedirectStrategy(new DefaultRedirectStrategy() {

            @Override
            protected boolean isRedirectable(String method) {
                return false;
            }

            @Override
            public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
                return false;
            }

        }).build();
        HttpPost request = new HttpPost(LOGIN_URL);
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        formparams.add(new BasicNameValuePair("LoginForm[email]", USERNAME));
        formparams.add(new BasicNameValuePair("LoginForm[password]", PASSWORD));
        formparams.add(new BasicNameValuePair("LoginForm[rememberMe]", "0"));
        formparams.add(new BasicNameValuePair("LoginForm[rememberMe]", "1"));
        formparams.add(new BasicNameValuePair("yt0", "Đăng nhập"));
        formparams.add(new BasicNameValuePair("fs_csrf", fs_csrf));
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
        request.setHeader(":host", "www.fshare.vn");
        request.setHeader(":method", "POST");
        request.setHeader(":path", "/login");
        request.setHeader(":scheme", "https");
        request.setHeader(":version", "HTTP/1.1");
        request.setHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        request.setHeader("accept-encoding", "gzip, deflate");
        request.setHeader("accept-language", "vi,en;q=0.8,es;q=0.6,ko;q=0.4,ja;q=0.2");
        request.setHeader("cache-control", "max-age=0");
        request.setHeader("content-type", "application/x-www-form-urlencoded");
        String cookie = String.format("session_id=%s; advertising_popup=closed", sessionIdGet);
        request.setHeader("cookie", cookie);
        request.setHeader("origin", "https://www.fshare.vn");
        request.setHeader("referer", "https://www.fshare.vn/");
        request.setHeader("user-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36");

        request.setEntity(entity);
        CloseableHttpResponse response = client.execute(request);
//        System.out.println("Status: " + response.getStatusLine().toString());
        Header[] headers = response.getAllHeaders();
        for (Header header : headers) {
            String name = header.getName();
//            System.out.println(String.format("%s: %s", name, header.getValue()));
            if (name.equalsIgnoreCase("set-cookie")) {
                HeaderElement[] elements = header.getElements();
                for (HeaderElement element : elements) {
                    String elementName = element.getName();
                    if (elementName.equalsIgnoreCase("session_id")) {
                        sessionIdPost = element.getValue();
//                        System.out.println("session_id POST: " + sessionIdPost);
                        break;
                    }
                }
            }
        }
        if (sessionIdPost.isEmpty()) {
            throw new Exception("Can't get session_id POST");
//            System.out.println("Can't get session_id POST");
//            sessionIdPost = sessionIdGet;
        }

//        writeResponseToFile(response, "D://LoginPost.html");
//        System.out.println("FINISH LOGIN POST!");
        client.close();
    }

    private void writeResponseToFile(CloseableHttpResponse response, String file) throws IOException {
        StringBuilder builder = new StringBuilder();
        InputStream content = response.getEntity().getContent();
        BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
        String s;
        while ((s = buffer.readLine()) != null) {
            builder.append(s).append("\n");
        }
        FileWriter writer = new FileWriter(file);
        writer.write(builder.toString());
    }
    
    public void logout() throws IOException, Exception {
        sessionIdGet = "";
        CloseableHttpClient client = HttpClientBuilder.create().build();
        HttpGet request = new HttpGet(LOGOUT_URL);
        String cookie = String.format("session_id=%s", sessionIdPost);
        request.setHeader("cookie", cookie);
        client.execute(request);        
//        writeResponseToFile(response, "D://logout.html");
//        System.out.println("FINISH LOGOUT!");
        client.close();
    }

    public static void main(String[] args) throws IOException, Exception {
        FshareTools app = new FshareTools();
        app.loginGet();
        app.loginPost();
        app.download(args[0]);
        app.logout();
    }
}
